import common from './common'
import SVG, { PathArray } from 'svg.js'
import { trim } from '../../libs/util'

const SPACE_COEFF = 1 / 3 //空格宽度系数
const TEXT_SCALE = 0.89 //文字补偿宽度系数
let TEXT_Y_MAKE_UP = 0 //起始Y轴坐标补偿值

const domSvg = document.createElement('svg')
const svg = SVG(domSvg)

/**
 * 数组求和
 * @returns {number}
 */
function arraySum () {
  let num = 0, arg = arguments
  for (let v of arg) {
    if (v.length > 0) num += eval(v.join('+'))
  }
  return num
}

/**
 * 起始x坐标偏移
 * @param x
 * @returns {number}
 * @constructor
 */
const StartXOffset = x => {
  const b = 27.25
  const k = -0.97
  return k * x + b
}

/**
 * 间距计算
 * @param num
 * @param size
 * @returns {number}
 */
const absoluteSpacing = (num, size) => +(num * size / 100).toFixed(2)

/**
 * 重置大小
 * @returns {{x: number, y: number, width: number, height: number, rotate: number}}
 */
const resetSize = () => ({
  x: 0,
  y: 0,
  width: 0,
  height: 0,
  rotate: 0
})
/**
 * 计算大小
 * @param current
 */
const calculateSize = (current) => {
  svg.clear()
  let size = {...resetSize(), ...current}
  if (size.rotate > 0 && size.width > 0) {
    if (size.cx === undefined) size.cx = size.width / 2
    if (size.cy === undefined) size.cy = size.height / 2
  }
  size.letterSpacing = !current.letterSpacing ? 0 : absoluteSpacing(current.letterSpacing, size.fontSize)
  size.lineSpacing = !current.lineSpacing ? 0 : absoluteSpacing(current.lineSpacing, size.fontSize)

  size.letterSpacing += 5

  if (Array.isArray(size.fontPaths) && size.fontPaths.length > 0) {
    let fontPaths = []
    let fontPaths_X = []
    let fonts = []
    let spaceFixedWidth = size.fontSize * SPACE_COEFF
    let lineWidth = [] //行宽
    let lineOffset = [] //行偏移
    TEXT_Y_MAKE_UP = size.fontSize * 0.3 //设置默认Y坐标偏移量
    // 第一次循环
    for (let index = 0; size.fontPaths.length > index; index++) {
      let item = size.fontPaths[index] //字体路径组
      let path_width = [] //计算路径宽度集合
      let startSlice = 0 //超出时位置
      let endSlice = 0
      let offset = 0
      let offset_index = 0
      // 第二次循环
      for (let i = 0; item.length > i; i++) {
        let flag = false
        const val = item[i]
        let tBbox = !!trim(val) ? new PathArray(val) : null
        const bbox = tBbox ? tBbox.bbox() : null
        const width = tBbox ? bbox.width : spaceFixedWidth //获取单个文字宽度
        TEXT_Y_MAKE_UP = tBbox && index === 0 && Math.abs(bbox.y) > TEXT_Y_MAKE_UP ? Math.abs(bbox.y) : TEXT_Y_MAKE_UP// 获取首行偏移Y坐标

        let x = offset + arraySum(path_width.slice(startSlice)) + size.letterSpacing * offset_index
        if (i === 0) {
          x = offset = tBbox ? StartXOffset(width) : 0
        }
        offset_index++
        if (x > size.width) {  //X轴坐标
          offset_index = 1
          offset = 0
          endSlice = i
          if (tBbox) {
            offset += StartXOffset(width)
          }
          x = offset
          flag = true
        } else if (x + width > size.width) { //X轴坐标 + 文字或空格
          offset_index = 0
          offset = 0
          endSlice = tBbox ? i : i + 1
          if (tBbox) {
            x = offset = StartXOffset(width)
            offset_index = 1
          }
          flag = true
        }

        fontPaths_X.push({x, font: size.fonts[index][i], width})
        path_width.push(width)
        if (i === 0 || flag) lineOffset.push(offset)

        if (tBbox) {
          tBbox = tBbox.move(x, bbox.y)
          item[i] = tBbox.toString()
        } else {
          item[i] = {width, x}
        }
        if (endSlice > startSlice && flag) {
          fontPaths.push(item.slice(startSlice, endSlice))
          fonts.push(size.fonts[index].slice(startSlice, endSlice))
          startSlice = endSlice
          const prev_bbox = fontPaths_X[i - 1]
          lineWidth.push({width: prev_bbox.x + prev_bbox.width - offset, offset})
        }
        if (item.length - 1 <= i) {
          fontPaths.push(item.slice(startSlice))
          fonts.push(size.fonts[index].slice(startSlice))
          lineWidth.push({width: x + width - offset, offset})
        }
      }
    }
    // 文字对齐方式
    let textAligns = []
    for (let val of lineWidth) {
      if (size.textAlign === 'center') {
        textAligns.push((size.width - val.width) / 2 + val.offset / 2)
      } else if (size.textAlign === 'right') {
        textAligns.push(size.width - val.width - val.offset / 2)
      } else {
        textAligns.push(0)
      }
    }
    console.log(lineWidth, '行宽度')
    console.log(lineOffset, '行偏移')
    console.log(fontPaths_X, '所有字体X坐标')
    size.fontPaths = fontPaths
    size.fonts = fonts
    size.textAligns = textAligns
  }
  size.height = (size.lineSpacing + size.fontSize) * (size.fontPaths.length - 1) + TEXT_Y_MAKE_UP
  return size
}

const handleMethods = {}

const TextPathHandler = {
  name: 'text-path-handler',
  props: {
    id: String,               // 编号
    value: {                   // 定位、宽高
      type: Object,
      default: resetSize
    }
  },
  data () {
    return {
      current: calculateSize(this.value)
    }
  },
  computed: {},
  watch: {
    value: {
      handler (size, oldVal) {
        this.current = calculateSize(size)
      },
      deep: true
    }
  },
  render (h) {
    const shape = this.current
    const viewBox = `0 0 ${shape.width} ${shape.height}`
    return (
      <g transform={common.matrix(shape)} data-type="textPath" className="parentGroup"
         style="opacity: 1;">
        <svg width={shape.width} height={shape.height} viewBox={viewBox} style={`${shape.style};overflow:auto;`}>
          <defs></defs>
          <rect width={shape.width} height={shape.height} opacity="0" className="textPathRect" stroke="#fff"
                fill="none"/>
          {
            shape.fontPaths.map(function (item, index) {
              return <g className="textPathGroup" fill={shape.color}
                        transform={common.matrix({
                          x: shape.textAligns[index],
                          y: (shape.fontSize + shape.lineSpacing) * index + TEXT_Y_MAKE_UP
                        })}>
                {
                  item.map(function (path, i) {
                    return trim(shape.fonts[index][i]) ?
                      <path d={path} data-value={shape.fonts[index][i]}/>
                      :
                      <rect width={path.width} height={2} x={path.x} opacity={0}
                            fill={i % 2 > 0 ? '#000' : '#fff'}/>
                  })
                }
              </g>
            })
          }
        </svg>
      </g>
    )
  },
  methods: {
    ...handleMethods
  }
}

export default TextPathHandler
